package com.protocols.sctp.m3ua.sccp.tcap;

import java.io.Serializable;
import java.math.BigInteger;

import com.protocols.BinaryInteger;
import com.protocols.OctaveInteger;
import com.protocols.ProtoOperations;
import com.protocols.ProtocolStackException;
import com.protocols.sctp.m3ua.sccp.SccpUnitDataMsg;

public abstract class TcapTag implements Serializable{

	public abstract byte [] decode(byte [] input) throws ProtocolStackException;
	private BinaryInteger TagClass = new BinaryInteger(2,6);
	private BinaryInteger TagForm = new BinaryInteger(1,5);
	private int TagCode = 0;

	public TcapTag() {
		
	}
	
	public TcapTag(int tag) {
		
		setTag(tag);
	}
	
	public  void setTag(int tagclass, int tagform, int tagcode) {
		TagClass.setValue(tagclass);
		TagForm.setValue(tagform);
		TagCode=tagcode;
	}
	
	public void setTag(int tag) {
		if (tag<0xff){
			TagClass.setValue((tag & 0xc0)>>6);
			TagForm.setValue((tag & 0x20)>>5);
			TagCode=(tag & 0b00011111);
		}
		else if (tag<0xffff){
			TagClass.setValue((tag & 0xc000)>>14);
			TagForm.setValue((tag & 0x2000)>>13);
			TagCode=(tag & 0xff);
		}
		else
		{
			TagClass.setValue((tag & 0xc00000)>>22);
			TagForm.setValue((tag & 0x200000)>>21);
			TagCode=(tag & 0x7f00)>>1 | (tag & 0xff);
			
		}
	}
	
	
	

	protected byte [] getTagBytes(int contentlength){
		
		int Length = contentlength;
		byte [] tag;

		int val31=31;
		if (TagCode<31){
			byte [] temp= {(byte)(TagClass.getOffsetValue()|TagForm.getOffsetValue()|TagCode)};
			tag=temp;
		}
		else if (TagCode<128){
			
			byte [] temp= {(byte)(TagClass.getOffsetValue()|TagForm.getOffsetValue()|val31),(byte)TagCode};
			
			tag=temp;
		}
		else if (TagCode<16384){
			
			byte [] temp= {(byte)(TagClass.getOffsetValue()|TagForm.getOffsetValue()|val31),(byte)((TagCode>>7)|0b10000000),(byte)(TagCode&0xff)};
			
			tag=temp;
		}
		else{
			
			byte [] temp= {(byte)(TagClass.getOffsetValue()|TagForm.getOffsetValue()|val31),(byte)((TagCode>>14)|0b10000000),(byte)((TagCode>>7)|0b10000000),(byte)(TagCode&0xff)};
			
			tag=temp;
		}
		
		byte [] len;
		
		if (Length<128){
			byte [] temp={(byte)Length};
			len=temp;
		}
		else {
			byte [] len1=BigInteger.valueOf(Length).toByteArray();
			if (len1[0]==0){		// remove the first zero if exist
				byte[] len12 = new byte[len1.length-1]; 
				System.arraycopy(len1, 1, len12, 0, len1.length-1);
				len1=len12;
			}
			
			byte [] len2={(byte)(0b10000000|(len1.length))};
			
			len= ProtoOperations.concatArrays(len2,len1);
		}
	
		return ProtoOperations.concatArrays(tag, len);
		
	}

	

	public int getTagCode() {
		return TagCode;
	}

	
	public void setTagCode(int tagCode) {
		TagCode = tagCode;
	}
	
	public void setTagCode(byte [] tagaray) {
		
	}

	public int getTagClass() {
		return TagClass.getValue();
	}

	public int getTagForm() {
		return TagForm.getValue();
	}
	
	
}
